package cn.winwintech.Incense.service;

import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSException;
import com.base.webapp.respm.OperationResp;
import com.base.webapp.respm.PageData;
import com.base.webapp.respm.ResException;

import cn.winwintech.Incense.client.request.OperationReq.OperationBean;
import cn.winwintech.Incense.client.response.TokenResp;
import cn.winwintech.Incense.dao.TreeDao;
import cn.winwintech.Incense.dao.UserDao;
import cn.winwintech.Incense.exception.ResExceptionFactory;
import cn.winwintech.Incense.model.Operation;
import cn.winwintech.Incense.model.Tree;
import cn.winwintech.Incense.model.TreeType;
import cn.winwintech.Incense.model.User;
import cn.winwintech.Incense.util.OssClientHelper;

@Service
public class UserService extends ServiceBase {
	public static final int pageSize = 50;
	private static Logger logger = Logger.getLogger(UserService.class);

	// 默认头像

	public static final int OK = 0;
	public static final int PHONE_EXIST = 1;
	public static final int INVITER_NOT_EXIST = 2;
	public static final int USER_NOT_EXIST = 3;
	public static final int PASSWORD_ERROR = 4;
	public static final int PROFILE_EXIST = 5;
	public static final int PROFILE_NOT_EXIST = 6;

	@Autowired
	private UserDao dao;
	@Autowired
	private TreeDao tDao;
	@Autowired
	private PasswordEncoder passwordEncoder;

	OssClientHelper client = OssClientHelper.shareClient();

	@Transactional(readOnly = true)
	public int checkUser(String userName, String password) {
		User user = dao.findUserByPhone(userName);
		if (user == null) {
			return USER_NOT_EXIST;
		}
		if (passwordEncoder.matches(password, user.getPassword())) {
			return OK;
		}
		return PASSWORD_ERROR;
	}

	@Transactional
	public TokenResp refreshTokenByPhone(String userName) {
		User user = dao.findUserByPhone(userName);
		return new TokenResp(dao.refreshToken(user));
	}

	@Transactional
	public TokenResp refreshTokenByToken(String token) throws ResException {
		User user = dao.findUserByTokenNotNull(token);
		return new TokenResp(dao.refreshToken(user));
	}

	@Transactional
	public int modifyPaswd(String phone, String password) {
		User user = dao.findUserByPhone(phone);
		if (user == null) {
			return USER_NOT_EXIST;
		}
		String encordPassword = password;
		if (passwordEncoder != null) {
			encordPassword = passwordEncoder.encode(password);
			logger.debug("encordPassword = " + encordPassword);
		}
		user.setPassword(encordPassword);
		dao.save(user);
		return OK;
	}

	@Transactional(rollbackForClassName = { "IllegalArgumentException","RuntimeException","ResException", "IllegalStateException", "OSSException", "ClientException",
			"IOException" })
	public boolean synchronizeUpload(OperationBean operations, String token, MultipartFile multipartFile,
			MultipartFile multipartFile2, MultipartFile multipartFile3, MultipartFile multipartFile4)
					throws ResException, IllegalStateException, IOException {
		User user = dao.findUserByTokenNotNull(token);
		if (user == null) {
			throw ResExceptionFactory.userNotExist();
		}
		Operation operation = new Operation();
		Tree tree = tDao.saveTree(operations.getTreeId(), operations.getTreeType(), operations.getLatitude(),
				operations.getLongitude());
		operation.setTree(tree);
		Timestamp createdAt = new Timestamp(operations.getCreatedAt());
		operation.setCreatedAt(createdAt);
		operation.setComment(operations.getComment());
		operation.setHumidity(operations.getHumidity());
		operation.setMethod(operations.getMethod());
		operation.setTemperature(operations.getTemperature());
		operation.setTrCoverarea(operations.getTrCoverArea());
		operation.setSubtype(operations.getSubtype());
		operation.setTrHeight(operations.getTrHeight());
		operation.setTrHightDiameter(operations.getTrHightDiameter());
		operation.setTrLowDiameter(operations.getTrLowDiameter());
		operation.setType(operations.getType());
		operation.setWeather(operations.getWeather());
		operation.setWind(operations.getWind());
		operation.setOperaterBy(user);

		// 保存图片
		String imageName = user.getId() + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
		if (multipartFile != null) {
			operation.setPhoto1(saveFile(multipartFile, imageName + "_1.jpg", client));
		}
		if (multipartFile2 != null) {
			operation.setPhoto2(saveFile(multipartFile2, imageName + "_2.jpg", client));
		}
		if (multipartFile3 != null) {
			operation.setPhoto3(saveFile(multipartFile3, imageName + "_3.jpg", client));
		}
		if (multipartFile4 != null) {
			operation.setPhoto4(saveFile(multipartFile4, imageName + "_4.jpg", client));
		}
		dao.save(operation);
		return true;
	}

	private String saveFile(MultipartFile multipartFile, String photoName, OssClientHelper client)
			throws OSSException, ClientException, IOException {
		// String photo = photoName + multipartFile.getOriginalFilename();
		client.putObject(OssClientHelper.BUCKETNAME, photoName, multipartFile.getInputStream());
		String url = client.generateThumbnailUrl(photoName);
		return url;
	}

	@Transactional(readOnly = true, rollbackForClassName = { "RuntimeException" })
	public PageData<OperationResp> download(int page, String maxUpdateAt) throws RuntimeException {
		PageData<OperationResp> resp = new PageData<>();
		long maxUpdateAtTime = 0L;
		if (maxUpdateAt != null && !maxUpdateAt.isEmpty()) {
			maxUpdateAtTime = Long.parseLong(maxUpdateAt);
		}
		resp.setPage(page);
		List<Operation> list = dao.findOperationList(page, maxUpdateAtTime);
		if (list == null) {
			return resp;
		}
		int totalNum = list.size();
		int totalPage = totalNum / pageSize + totalNum % pageSize == 0 ? 0 : 1;
		resp.setDownloadPage(totalPage);
		resp.setTotalNum(totalNum);

		for (Operation operation : list) {
			OperationResp operationResp = new OperationResp();
			operationResp.setOptId(operation.getId());
			operationResp.setComment(operation.getComment());
			operationResp.setTreeId(operation.getTree().getTreeId());
			operationResp.setPhoto1(operation.getPhoto1());
			operationResp.setPhoto2(operation.getPhoto2());
			operationResp.setPhoto3(operation.getPhoto3());
			operationResp.setPhoto4(operation.getPhoto4());
			operationResp.setHumidity(operation.getHumidity());
			operationResp.setMethod(operation.getMethod());
			operationResp.setTemperature(operation.getTemperature());
			operationResp.setTrCoverArea(operation.getTrCoverarea());
			operationResp.setSubtype(operation.getSubtype());
			operationResp.setTrHeight(operation.getTrHeight());
			operationResp.setTrHightDiameter(operation.getTrHightDiameter());
			operationResp.setTrLowDiameter(operation.getTrLowDiameter());
			TreeType type = operation.getTree().getType();
			if (type != null) {
				operationResp.setTreeType(type.getId());
			}

			operationResp.setLongitude(operation.getTree().getLongitude()+"");
			operationResp.setLatitude(operation.getTree().getLatitude()+"");
			operationResp.setType(operation.getType());
			operationResp.setWeather(operation.getWeather());
			operationResp.setWind(operation.getWind());
			operationResp.setUpdateBy(operation.getOperaterBy().getName());
			operationResp.setCreatedAt(operation.getCreatedAt().getTime() + "");
			operationResp.setUpdateAt(operation.getUpdateAt().getTime() + "");
			resp.add(operationResp);
		}
		return resp;

	}

}
